﻿using System;
using System.Collections.Generic;
using ICSharpCode.TextEditor.Document;

namespace LuaVM.Controls
{
    /// <summary>
    /// Lua折叠策略
    /// </summary>
	class LuaFoldingStrategy : IFoldingStrategy
	{
        // Lua常见折叠关键词
        static readonly List<string> BlockHeads = new List<string> {
            "function", 
            "local function",
            "if",
            "for",
            "do",
            "while",
            "repeat",
        };

        /// <summary>
        /// 
        /// </summary>
        /// <param name="document"></param>
        /// <param name="fileName"></param>
        /// <param name="parseInformation"></param>
        /// <returns></returns>
        public List<FoldMarker> GenerateFoldMarkers(IDocument document, string fileName, object parseInformation)
        {
            List<FoldMarker> list = new List<FoldMarker>();
            Stack<MarkNode> startLines = new Stack<MarkNode>();

            for (int i = 0; i < document.TotalNumberOfLines; i++)
            {
                string text = document.GetText(document.GetLineSegment(i)).Trim();                

                foreach (string head in BlockHeads)
                {
                    if (StartWithKeywork(text, head))
                    {
                        MarkNode node = new MarkNode()
                        {
                            Index = i,
                            Keyword = head,
                        };

                        startLines.Push(node);
                    }
                }

                bool isTail = false;
                if (startLines.Count > 0)
				{
                    MarkNode node = startLines.Peek();
                    if (node.Keyword == "repeat")
					{
                        isTail = StartWithKeywork(text, "until");
                    }
                    else
					{
                        isTail = StartWithKeywork(text, "end");
                    }
				}

                if (isTail)
				{
                    MarkNode node = startLines.Pop();
                    list.Add(new FoldMarker(document, node.Index, document.GetLineSegment(node.Index).Length, i, 57, FoldType.TypeBody, "..."));
                }                
            }

            return list;
        }        

        private static bool StartWithKeywork(string line, string keyword)
		{
            if (string.IsNullOrEmpty(line))
			{
                return false;
			}

            string[] items = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            line = string.Join(" ", items);
            if (!line.StartsWith(keyword))
			{
                return false;
			}

            if (line.Length == keyword.Length)
			{
                return true;
			}

            char ch = line[keyword.Length];
            if (ch == '_' || char.IsLetterOrDigit(ch))
			{
                return false;
			}

            return true;
        }
    }

    class MarkNode
	{
        public int Index { get; set; }
        public string Keyword { get; set; }
	}
}
